package model.action.basic_function_action;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
import java.util.Random;

import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import model.dap.dao.ConsumerDAO;
import model.dap.dao.MailConfigDAO;
import model.dap.domain.Consumer;
import model.dap.domain.MailConfig;
import model.dap.mapper.ConsumerMapper;
import model.dap.mapper.MailConfigMapper;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ModelDriven;
import common.base.BaseAction;
import common.util.EmailValidator;
import common.util.ValidateUtil;

@Results({
	@Result(name = "retrievepasswordload", location = "/view/basic_function_view/Retrieve_password.jsp"),
	@Result(name = "error", type = "tiles", location = "tiles.error"),
	@Result(name = "successCx", type="redirectAction", location="retrieve-password.html"),
	@Result(name = "success", location = "/view/basic_function_view/Retrieve_password.jsp"),
	@Result(name = "successEx", location = "/view/basic_function_view/Retrieve_password_web.jsp"),
	@Result(name = "errorEx", location = "/view/basic_function_view/Retrieve_password.jsp"),
	@Result(name = "errorRx", location = "/view/basic_function_view/Retrieve_password_web.jsp"),
	@Result(name = "errorPx", type = "tiles", location = "error.jsp")})
@ParentPackage("master_tiles")
public class RetrievePasswordAction extends BaseAction implements ModelDriven<Consumer> {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected static Logger log = Logger.getLogger(RetrievePasswordAction.class);
	private static final String charset = "!@#$%^&*()" + "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	
	private Consumer consumer = new Consumer();
	private String email, passWord, temporaryPassword, userID;
	private static int errTimes=0;
	private String to;
	private int typeID;
	private static EmailValidator emv = new EmailValidator();
	
	public static int getErrTimes() {
		return errTimes;
	}
	public static void setErrTimes(int errTimes) {
		RetrievePasswordAction.errTimes = errTimes;
	}
	
	public String getTo() {
		return to;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public int getTypeID() {
		return typeID;
	}

	public void setTypeID(int typeID) {
		this.typeID = typeID;
	}
	// --- Bien cua mail------
		private static MailConfig mailConfig = new MailConfig();
		
		static Properties properties = new Properties();
		public static MailConfig getMailConfig() {
			return mailConfig;
		}

		public static void setMailConfig(MailConfig mailConfig) {
			RetrievePasswordAction.mailConfig = mailConfig;
		}

		public static Properties getProperties() {
			return properties;
		}

		public static void setProperties(Properties properties) {
			RetrievePasswordAction.properties = properties;
		}

	public String getUserID() {
		//userID = ServletActionContext.getRequest().getParameter("userID");
		return userID;
	}

	public void setUserID(String userID) {
		this.userID = userID;
	}

	public String getTemporaryPassword() {
		return temporaryPassword;
	}

	public void setTemporaryPassword(String temporaryPassword) {
		this.temporaryPassword = temporaryPassword;
	}

	public String getPassWord() {
		return passWord;
	}

	public void setPassWord(String passWord) {
		this.passWord = passWord;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Consumer getConsumer() {
		return consumer;
	}

	public void setConsumer(Consumer consumer) {
		this.consumer = consumer;
	}

	@Action("/master/retrieve-password")
	public String retrieve_password() {
		getCityList2();
		loadParentDealCategory();
		return "retrievepasswordload";
	}
	
	@Action("/master/retrievepassword")
	public String retrieve_Password()
	{	
		try {
			String type = ServletActionContext.getRequest().getMethod();
			
			if(type.toUpperCase() == "GET")
			{
				return "successCx";
			}
			getCityList2();
			loadParentDealCategory();
			consumer.setUserID(consumer.getUserID());
			consumer.setEmail(consumer.getEmail());
			
			if(validateInputField() == false){
				return "errorEx";
			}
			
			updateTemporaryPassword();
			ConsumerMapper consumerMapper = new ConsumerDAO();
			consumer = consumerMapper.retrievePassword(consumer);
			
			if(consumer == null)
			{
				return ERROR;
			}
			//SEND EMAIL
			execute(consumer.getEmail(), 3);
			setSuccessmessage("Mật khẩu tạm thời của bạn đã được gửi vào email "+consumer.getEmail() + " của bạn. Vui lòng kiểm tra email để lấy lại mật khẩu.");
			return SUCCESS;
			
		} catch (Exception e) {
			// TODO: handle exception
			log.error(e.getMessage());
			return ERROR;
		}
		
	}
	
	// ---------------SEND MAIL
		public void execute(String sTo, int sTypeID) throws IOException {	      
			setTo(sTo);
			setTypeID(sTypeID);
			
			MailConfigMapper mailConfigMapper = new MailConfigDAO();
			mailConfig = mailConfigMapper.selectMailConfigByID(typeID);
			
			properties.put("mail.smtp.host", mailConfig.getSmtpHost());
			String socketPort=(" "+mailConfig.getSmtpSocketPort()).trim();
			String socketClass=(" "+mailConfig.getSmtpSocketClass()).trim();
			
			if(ValidateUtil.validateEmptyString(socketPort)==false&&ValidateUtil.validateEmptyString(socketClass)==false){
				properties.put("mail.smtp.socketFactory.port", mailConfig.getSmtpSocketPort());
				properties.put("mail.smtp.socketFactory.class",	mailConfig.getSmtpSocketClass());
			}
			properties.put("mail.smtp.auth", mailConfig.getSmtpAuth());
			properties.put("mail.smtp.port", mailConfig.getSmtpPort());
			properties.put("mail.smtp.password", mailConfig.getPassword());
	        
			try {
				if(ValidateUtil.validateEmptyString(socketPort)==false&&ValidateUtil.validateEmptyString(socketClass)==false){
					Session session = Session.getDefaultInstance(properties,
							new javax.mail.Authenticator() {
								protected PasswordAuthentication getPasswordAuthentication() {
									return new PasswordAuthentication(mailConfig.getFrom(), mailConfig.getPassword());
								}
							});
					
					// encording utf8 - subject
					byte[] pSubject = mailConfig.getSubject().getBytes("UTF-8");
					String subjectValue = new String(pSubject, "UTF-8");
					// encording utf8 - subject
					String iBody=mailConfig.getBody();
					byte[] pBody = iBody.getBytes("UTF-8");
					String bodyValue = new String(pBody, "UTF-8");
					
					Message message = new MimeMessage(session);
					message.setFrom(new InternetAddress(mailConfig.getFrom()));
					message.setRecipients(Message.RecipientType.TO,
							InternetAddress.parse(to));
					message.setSubject(subjectValue);
					 message.setContent(bodyValue+consumer.getTemporaryPassword()+ " <br><a href='http://127.0.0.1:8080/CungDeal/view/basic_function_view/Retrieve_password_web.jsp?userID="+ consumer.getUserID() + "'>Nhấp vào đây:</a>","text/html; charset=utf-8");
					Transport.send(message);
					
				}else{
					// Get the default Session object.
			           Session session = Session.getDefaultInstance(properties,null);
			           
		              // Create a default MimeMessage object.
		              MimeMessage message = new MimeMessage(session);

		              // Set From: header field of the header.
		              message.setFrom(new InternetAddress(mailConfig.getFrom()));

		              // Set To: header field of the header.
		              message.addRecipient(Message.RecipientType.TO,
		                                       new InternetAddress(to));
						
		              // Set Subject: header field
		              message.setSubject(mailConfig.getSubject(), "UTF-8");

		              // get username in from
		              String[] fromItems = mailConfig.getFrom().split("@");
		              String username=fromItems[0];
		              
		              // Now set the actual message
		              message.setContent(mailConfig.getBody()+consumer.getTemporaryPassword()+ " <br><a href='http://127.0.0.1:8080/CungDeal/view/basic_function_view/Retrieve_password_web.jsp?userID="+ consumer.getUserID() + "'>Nhấp vào đây:</a>","text/html; charset=utf-8");
					Transport transport = session.getTransport("smtp");
					transport.connect(mailConfig.getSmtpHost(),username, mailConfig.getPassword());
					transport.sendMessage(message, message.getAllRecipients());
					transport.close();
				}

			} catch (Exception e) {
				setErrTimes(errTimes + 1);
				if(errTimes>1){
					log.error("Send mail register consumer fail for "+consumer.getUserID()+" with email address: "+to+ " times 2.");
					setErrTimes(0);
				}
				else{
					log.error("Send mail register consumer fail for "+consumer.getUserID()+" with email address: "+to+ " times 1.");
					execute(consumer.getEmail(), 1);
				}
			}
		}

	// Now set the actual message
	
	// create random tem password save in db
	public String updateTemporaryPassword()
	{
		// luu random tem password
		String random = getRandomString(10);
		consumer.setTemporaryPassword(random);
		ConsumerMapper consumerMapper = new ConsumerDAO();
		int results = consumerMapper.updateTemporaryPassword(consumer);
		
		//random = String.valueOf(consumerMapper.updateTemporaryPassword(consumer));
		if(results == 0)
		{
			return ERROR;
		}
		return SUCCESS;
	}
	
	// get ramdom string
	public String getRandomString(int lengh)
	{
		Random rand = new Random(System.currentTimeMillis());
		StringBuffer sb = new StringBuffer();
		for(int i = 0; i <= lengh; i++)
		{
			int pos = rand.nextInt(charset.length());
			sb.append(charset.charAt(pos));
		}
		return sb.toString();
	}
	
	// retrieve password
	private String password, confirmNewPassword;

	@Action("/master/update-password1")
	public String updatePasswordWeb()
	{
		getCityList2();
		loadParentDealCategory();
		// GET PASSWORD AND PARSE TO MD5 CODE
		password = consumer.getNewPassword();
		confirmNewPassword = consumer.getConfirmNewPassword();
		try {
			if (ValidateUtil.validateEmptyString(password) == false && 
				ValidateUtil.validateEmptyString(confirmNewPassword) == false) 
			{
				consumer.setNewPassword(ValidateUtil.MD5Encryption(password));
				consumer.setConfirmNewPassword(ValidateUtil.MD5Encryption(confirmNewPassword));
			}
		}

		catch (NoSuchAlgorithmException a) {
			a.printStackTrace();
		}

		catch (UnsupportedEncodingException a) {
			a.printStackTrace();
		}
		
		
		try {
			if(validateInputField1() == false)
			{
				return "errorRx";
			}
			
			ConsumerMapper consumerMapper = new ConsumerDAO();
			int cons = consumerMapper.updatePassword(consumer);
			
			if(cons == 0)
			{
				return "errorPx";
			}
			setSuccessmessage("Cập nhật mật khẩu mới thành công!");
			return "successEx";
		} catch (Exception e) {
			// TODO: handle exception
			return "errorPx";
		}
		
	}
	
	/*
	 * Validate input input form return message, true or false
	 */
	public boolean validateInputField()
	{
		boolean check = true;
		// validate email
		if(ValidateUtil.validateEmptyString(consumer.getEmail()) == true)
		{
			showError("Email không được để trống");
			check = false;
		}
		// validate userID
		if(ValidateUtil.validateEmptyString(consumer.getUserID()) == true)
		{
			showError("UserID không được để trống");
			check = false;
		}
		// validate length userID
		if (ValidateUtil.validateLengthOfUserID(consumer.getUserID()) == false) {
			showError("Chiều dài tên đăng nhập từ 6 đến 25 kí tự");
			check = false;
		}
		// validate email standard
		if (emv.validate(consumer.getEmail()) == false) {
			showError("Email không hợp lệ");
			check = false;
		}
		// validate email matching userID
		if(ValidateUtil.validateEmailMatchUserID(consumer) == false)
		{
			showError("Email và tên tài khoản không hợp lệ");
			check = false;
		}
		
		return check;
	}
	
	//
	public boolean validateInputField1() {
		boolean check = true;

		// validate temporary password
		if (ValidateUtil.validateTemporaryPassword(consumer.getTemporaryPassword()) == false) {
			showError("Temporary password không hợp lệ");
			check = false;
		}
		// validate new password
		if (ValidateUtil.validateEmptyString(consumer.getNewPassword()) == true) {
			showError("Mật khẩu không được để trống");
			check = false;
		}
		// validate confirm new password
		if (ValidateUtil.validateEmptyString(consumer.getConfirmNewPassword()) == true) {
			showError("Mật khẩu xác nhận không được để trống");
			check = false;
		}
		//
		if (ValidateUtil.validateLengthOfPassword(consumer.getNewPassword()) == false) {
			showError("Chiều dài mật khẩu từ 6 đến 50 kí tự");
			check = false;
		}
		// validate new password and confirm new password
		if (ValidateUtil.validateConfirmPassword(consumer.getNewPassword(), consumer.getConfirmNewPassword()) == false) {
			showError("Mật khẩu và xác nhận mật khẩu không đúng");
			check = false;
		}

		return check;
	}

	@Override
	public Consumer getModel() {
		// TODO Auto-generated method stub
		return consumer;
	}
}
